package scau.filesystem.util.reflect;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import scau.filesystem.bean.Student;

public class ReflectControlImpl implements ReflectControl{
	
	private Class clazz;
	
	private Map<String, Field> fieldMap;
	
	public ReflectControlImpl() {}
	
	public ReflectControlImpl(String classname){
		fieldMap = new HashMap<>();
		initClass(classname);
	}
	
	@Override
	public void initClass(String classname) {
		try {
			clazz = Class.forName(classname);
			Field[] fields = clazz.getDeclaredFields();
			for(Field f : fields){
				fieldMap.put(f.getName(), f);
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public Object getFieldValue(String field, Object t) {
		Object b = null;
		try {
			b = get(fieldMap.get(field), t);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return b;
	}

	@Override
	public void setFieldValue(String field, Object value, Object t) {
		Field f = fieldMap.get(field);
		try {
			set(f, value, t);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private Object get(Field f, Object t) throws IllegalArgumentException, IllegalAccessException{
		boolean b = f.isAccessible();
		f.setAccessible(true);
		String type = f.getType().getSimpleName();
		Object result = null;
		switch (type) {
		case "String":
			result = f.get(t);
			break;
		case "int":
			result = f.getInt(t);
			break;
		case "double":
			result = f.getDouble(t);
			break;
		case "byte":
			result = f.getByte(t);
			break;
		case "boolean":
			result = f.getBoolean(t);
			break;
		default:
			result = f.get(t);
			break;
		}
		f.setAccessible(b);
		return result;
	}
	
	private void set(Field f, Object value, Object t) throws IllegalArgumentException, IllegalAccessException{
		boolean b = f.isAccessible();
		f.setAccessible(true);
		String type = f.getType().getSimpleName();
		switch (type) {
		case "int":
			f.setInt(t, (int)value);
			break;
		case "double":
			f.setDouble(t, (double)value);
			break;
		case "byte":
			f.setByte(t, (byte)value);
			break;
		default:
			f.set(t, value);
			break;
		}
		f.setAccessible(b);
	}
	
	public static void main(String[] args) {
		Student s = new Student();
		Class cla = s.getClass();
		Field[] fields = cla.getDeclaredFields();
		for(Field f : fields){
			System.out.println(f.getName());
			System.out.println(f.getType());
		}
	}

}
